﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using LDSBusiness;
using LDSBusiness.EventArgs;
using LDSCore;
using LDSModel;
using LDSModel.Dal;
using LDSProject.Properties;

namespace LDSProject.Forms
{
    public partial class OilTankForm : Form
    {
        readonly Guid _oilTankId;
        List<Data_Device> _deviceList;
        Dictionary<Guid, List<Data_Records>> _dataList;

        public OilTankForm(Guid oilTankId)
        {
            InitializeComponent();

            _oilTankId = oilTankId;
        }

        private void OilTankForm_Load(object sender, EventArgs e)
        {
            _dataList = new Dictionary<Guid, List<Data_Records>>();
            var oilTank = DeviceService.Instance.GetOilTank(_oilTankId);

            Text = oilTank.Name;
            lbTitle.Text = oilTank.Name;

            _deviceList = DeviceService.Instance.LoadDeviceList(_oilTankId);

            var index = 1;

            foreach (var device in _deviceList)
            {
                if (device != null)
                {
                    if (MainConsole.Instance.DevicePostion.ContainsKey(device.Index.Value))
                    {
                        var point = MainConsole.Instance.DevicePostion[device.Index.Value];

                        var pb = new PictureBox
                            {
                                Left = point.X,
                                Top = point.Y,
                                Name = device.DeviceId.ToString(),
                                Tag = "pbDevice" + index++
                            };
                        pb.MouseDoubleClick += pb_MouseDoubleClick;
                        pb.MouseEnter += MainConsole.Instance.pb_MouseEnter;
                        pb.MouseLeave += MainConsole.Instance.pb_MouseLeave;

                        pb.BackgroundImage = Resources.device;
                        pb.BackgroundImageLayout = ImageLayout.Stretch;
                        pb.SizeMode = PictureBoxSizeMode.StretchImage;
                        pb.Cursor = Cursors.Hand;
                        pb.Width = 38;
                        pb.Height = 29;

                        pb.Image = Resources.offline;
                        pb.BackColor = Color.Transparent;
                        pb.Enabled = false;

                        picMain.Controls.Add(pb);
                    }
                }

                ReSize();

                if (device == null) continue;
                MainConsole.Instance.CheckDeviceState(device.DeviceId, Instance_OnDeviceOnlineChanged, null);

                if (!_dataList.Keys.Contains(device.DeviceId))
                    _dataList.Add(device.DeviceId, new List<Data_Records>());
            }

            MainConsole.Instance.OnRecordReceived += Instance_OnRecordReceived;
            MainConsole.Instance.OnDeviceStateChanged += Instance_OnDeviceOnlineChanged;

            timer1.Start();
        }

        void Instance_OnDeviceOnlineChanged(object sender, DeviceStateChangedEventArgs args)
        {
            if (!IsDisposed)
                Invoke(new DelegateRefreshDevice(MainConsole.Instance.RefreshPictureBox), this, args.DeviceId, args.State);
        }

        void Instance_OnRecordReceived(object sender, RecordReceivedEventArgs args)
        {
            var device = DeviceService.Instance.GetDevice(args.Record.DeviceID);

            if (device == null) return;
            lock (_dataList)
            {
                List<Data_Records> records;
                _dataList.TryGetValue(device.DeviceId, out records);

                if (records == null)
                {
                    records = new List<Data_Records>();
                }
                else
                {
                    _dataList.Remove(device.DeviceId);
                }

                records.Add(args.Record);
                _dataList.Add(device.DeviceId, records);
            }

            if (!IsDisposed && MainConsole.Instance.CheckAlermValue(args.Record))
                Invoke(new DelegateRefreshDevice(MainConsole.Instance.RefreshPictureBox), this, args.Record.DeviceID, DeviceState.Alarm);
            var pb = picMain.Controls.Find(device.DeviceId.ToString(), false).FirstOrDefault() as PictureBox;
            if (null == pb) return;
            var panel = Controls.Find(pb.Tag.ToString(), false).FirstOrDefault() as Panel;

            if (!IsDisposed)
                Invoke(new DelegateRefreshValue(MainConsole.Instance.RefreshValue), args.Record.DeviceID, panel, _dataList, true);
        }

        void pb_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            var form = new DeviceForm(Guid.Parse(((PictureBox)sender).Name));
            form.ShowDialog(this);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            lock (_dataList)
            {
                foreach (var device in _deviceList)
                {
                    List<Data_Records> records;
                    _dataList.TryGetValue(device.DeviceId, out records);

                    if (null != records && records.Count > 0)
                    {
                        records = records.FindAll(r => r.AlarmTime != null && DateTime.Now.Subtract(r.AlarmTime.Value).TotalSeconds < Settings.Default.AlermTimeOut);

                        _dataList.Remove(device.DeviceId);
                        _dataList.Add(device.DeviceId, records);
                    }

                    var pb = picMain.Controls.Find(device.DeviceId.ToString(), false).FirstOrDefault() as PictureBox;
                    if (null == pb) continue;
                    var panel = Controls.Find(pb.Tag.ToString(), false).FirstOrDefault() as Panel;

                    if (!IsDisposed)
                        Invoke(new DelegateRefreshValue(MainConsole.Instance.RefreshValue), device.DeviceId, panel, _dataList, true);
                }
            }
        }

        private void OilTankForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer1.Stop();
            MainConsole.Instance.OnRecordReceived -= Instance_OnRecordReceived;
            MainConsole.Instance.OnDeviceStateChanged -= Instance_OnDeviceOnlineChanged;
        }

        private void picMain_Resize(object sender, EventArgs e)
        {
            ReSize();
        }

        private void ReSize()
        {
            var size = new Size(38, 29);
            var blWidth = (float)picMain.Width / picMain.Image.Width;
            var blHeight = (float)picMain.Height / picMain.Image.Height;
            var bl = Math.Min(blWidth, blHeight);
            var offsetWidth = 0;
            var offsetHeight = 0;
            if (blWidth > blHeight)
            {
                offsetWidth = (picMain.Width - (int)(picMain.Image.Width * bl)) / 2;
            }
            else
            {
                offsetHeight = (picMain.Height - (int)(picMain.Image.Height * bl)) / 2;
            }

            foreach (var pic in picMain.Controls.OfType<PictureBox>())
            {
                Point point;
                MainConsole.Instance.DevicePostion.TryGetValue(int.Parse(pic.Tag.ToString().Replace("pbDevice", "")), out point);
                if (!point.IsEmpty)
                {
                    pic.Left = offsetWidth + (int)(point.X * bl);
                    pic.Top = offsetHeight + (int)(point.Y * bl);
                    pic.Width = (int)(size.Width * bl);
                    pic.Height = (int)(size.Height * bl);
                }

                var panel = Controls.Find(pic.Tag.ToString(), true).FirstOrDefault() as Panel;
                if (null == panel) continue;
                panel.Left = pic.Left - panel.Width - 10;
                panel.Top = pic.Top - 20;
            }
        }
    }
}
